package org.mx.service.server;

import org.mx.StringUtils;
import org.mx.TypeUtils;
import org.springframework.beans.factory.annotation.Value;

import lombok.Getter;
import lombok.Setter;

/**
 * 描述： RESTful服务配置对象
 *
 * @author john peng Date time 2018/7/18 下午1:17
 */
public class WebsocketServerConfigBean extends HttpServerConfigBean {
	@Value("${websocket.enabled:false}")
	@Getter
	private boolean enabled;
	@Value("${websocket.host:0.0.0.0}")
	@Getter
	@Setter
	private String host;
	@Value("${websocket.port:9999}")
	@Getter
	@Setter
	private int port;
	@Value("${websocket.echo.enabled:true}")
	@Getter
	private boolean echoEnabled;
	@Value("${websocket.threads:100}")
	@Getter
	private int threads;
	@Value("${websocket.security:false}")
	@Getter
	private boolean security;
	@Value("${websocket.security.keystore:}")
	@Getter
	private String keystorePath;
	@Value("${websocket.security.keystorePassword:}")
	@Getter
	private String keystorePassword;
	@Value("${websocket.security.keyManagerPassword:}")
	@Getter
	private String keyManagerPassword;
	@Value("${websocket.security.keystoreType:JKS}")
	@Getter
	private String keystoreType;
	@Value("${websokcet.security.keyAlias:jetty}")
	@Getter
	private String keyAlias;
	@Value("${websokcet.security.keyManagerFactoryAlgorithm:SunX509}")
	@Getter
	private String keyManagerFactoryAlgorithm;
	@Value("${websokcet.security.maxCertPathLength:-1}")
	@Getter
	private int maxCertPathLength;
	@Value("${websokcet.security.validatCerts:false}")
	@Getter
	private boolean validateCerts;
	@Value("${websokcet.security.validatePeerCerts:false}")
	@Getter
	private boolean validatePeerCerts;
	@Value("${websokcet.security.needClientAuth:false}")
	@Getter
	private boolean needClientAuth;
	@Value("${websokcet.security.wantClientAuth:false}")
	@Getter
	private boolean wantClientAuth;

	@Value("${websocket.idleTimeoutSecs:300}")
	@Getter
	private long idleTimeoutSecs;
	@Value("${websocket.outputSize:32K}")
	private String outputSizeString;
	@Value("${websocket.requestHeaderSize:8K}")
	private String requestHeaderSizeString;
	@Value("${websocket.responseHeaderSize:8K}")
	private String responseHeaderSizeString;

	@Value("${websocket.security.cipherSuites:TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA384,TLS_DHE_RSA_WITH_AES_128_GCM_SHA384,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA256,TLS_DHE_RSA_WITH_AES_256_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_DHE_RSA_WITH_AES_256_GCM_SHA384}")
	private String cipherSuitesString;
	@Value("${websocket.security.protocols:TLSv1.2}")
	private String protocolsString;
	@Value("${websocket.session.ping.cycleSec:5}")
	@Getter
	private int pingCycleSec;
	@Value("${websocket.session.clean.cycleSec:30}")
	@Getter
	private int cleanCycleSec;
	@Value("${websocket.session.filter.rules:}")
	@Getter
	private String filterRulesString;
	@Value("${websocket.session.filter.rules.list.allows:}")
	@Getter
	private String filterRulesAllows;
	@Value("${websocket.session.filter.rules.list.blocks:}")
	@Getter
	private String filterRulesBlocks;
	@Value("${websocket.session.filter.rules.ddos.cycleSec:30}")
	@Getter
	private int filterRulesDdosCycleSec;
	@Value("${websocket.session.filter.rules.ddos.maxConnections:20}")
	@Getter
	private int filterRulesDdosMaxConnections;
	@Value("${websocket.asyncWriteTimeoutSecs:60}")
	@Getter
	private int asyncWriteTimeoutSecs;
	@Value("${websocket.inputBufferSize:4K}")
	private String inputBufferSizeString;
	@Value("${websocket.maxTextMessageSize:64K}")
	private String maxTextMessageSizeString;
	@Value("${websocket.maxTextMessageBufferSize:32K}")
	private String maxTextMessageBufferSizeString;
	@Value("${websocket.maxBinaryMessageSize:64K}")
	private String maxBinaryMessageSizeString;
	@Value("${websocket.maxBinaryMessageBufferSize:32K}")
	private String maxBinaryMessageBufferSizeString;

	@Value("${websocket.service.classes:}")
	private String serviceClasses;
	@Value("${websocket.service.base.packages:}")
	private String resourceBasePackages;

	/**
	 * 默认的构造函数
	 */
	public WebsocketServerConfigBean() {
		super(ServerType.WebSocket);
	}
	
	/**
	 * {@inheritDoc}
	 * 
	 * @see HttpServerConfigBean#getCipherSuites()
	 */
	public String[] getCipherSuites() {
		return StringUtils.split(cipherSuitesString, ",", true, true);
	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see HttpServerConfigBean#getProtocols()
	 */
	public String[] getProtocols() {
		return StringUtils.split(protocolsString, ",", true, true);
	}

	/**
	 * {@inheritDoc}
	 *
	 * @see HttpServerConfigBean#getOutputSize()
	 */
	public long getOutputSize() {
		return TypeUtils.string2Size(outputSizeString, 32 * 1024);
	}

	/**
	 * {@inheritDoc}
	 *
	 * @see HttpServerConfigBean#getRequestHeaderSize()
	 */
	public long getRequestHeaderSize() {
		return TypeUtils.string2Size(requestHeaderSizeString, 8 * 1024);
	}

	/**
	 * {@inheritDoc}
	 *
	 * @see HttpServerConfigBean#getResponseHeaderSize()
	 */
	public long getResponseHeaderSize() {
		return TypeUtils.string2Size(responseHeaderSizeString, 8 * 1024);
	}

	/**
	 * 获取WebSocket过滤器
	 * 
	 * @return 过滤器
	 */
	public WebSocketFilter getWebSocketFilter() {
		return new WebSocketFilter(StringUtils.split(filterRulesString), filterRulesAllows, filterRulesBlocks,
				filterRulesDdosCycleSec, filterRulesDdosMaxConnections);
	}

	/**
	 * 获取输入缓冲区大小
	 *
	 * @return 输入缓冲区大小
	 */
	public long getInputBufferSize() {
		return TypeUtils.string2Size(inputBufferSizeString, 4 * 1024);
	}

	/**
	 * 获取文本消息最大大小
	 *
	 * @return 文本消息最大大小
	 */
	public long getMaxTextMessageSize() {
		return TypeUtils.string2Size(maxTextMessageSizeString, 64 * 1024);
	}

	/**
	 * 获取文本消息最大缓冲区大小
	 *
	 * @return 文本消息最大缓冲区大小
	 */
	public long getMaxTextMessageBufferSize() {
		return TypeUtils.string2Size(maxTextMessageBufferSizeString, 32 * 1024);
	}

	/**
	 * 获取二进制消息最大大小
	 *
	 * @return 二进制消息最大大小
	 */
	public long getMaxBinaryMessageSize() {
		return TypeUtils.string2Size(maxBinaryMessageSizeString, 64 * 1024);
	}

	/**
	 * 获取二进制消息的最大缓冲区大小
	 *
	 * @return 二进制消息的最大缓冲区大小
	 */
	public long getMaxBinaryMessageBufferSize() {
		return TypeUtils.string2Size(maxBinaryMessageBufferSizeString, 32 * 1024);
	}
	
	/**
	 * 获取配置的WebSocket服务类列表
	 *
	 * @return WebSocket服务类类别
	 */
	public String[] getServiceClasses() {
		return StringUtils.split(serviceClasses);
	}

	/**
	 * 获取配置的WebSocket服务资源基准包路径，如果有多个包，用逗号分隔。系统将自动扫描。
	 *
	 * @return WebSocket服务资源基本包路径
	 */
	public String[] getResourceBasePackages() {
		String packages = StringUtils.isBlank(resourceBasePackages) ? super.getSpringBootClassPackage()
				: resourceBasePackages;
		return StringUtils.split(packages);
	}

	/**
	 * WebSocket过滤器
	 * 
	 * @author john.peng
	 *
	 */
	@Getter
	public class WebSocketFilter {
		private String[] filters;
		private String listAllows, listBlocks;
		private int ddosCycleSec, ddosMaxConnections;

		/**
		 * 构造函数
		 * 
		 * @param filters            过滤器列表
		 * @param listAllows         允许列表
		 * @param listBlocks         阻断列表
		 * @param ddosCycleSec       DDOS检查周期
		 * @param ddosMaxConnections DDOS最大连接数
		 */
		public WebSocketFilter(String[] filters, String listAllows, String listBlocks, int ddosCycleSec,
				int ddosMaxConnections) {
			super();
			this.filters = filters;
			this.listAllows = listAllows;
			this.listBlocks = listBlocks;
			this.ddosCycleSec = ddosCycleSec;
			this.ddosMaxConnections = ddosMaxConnections;
		}
	}
}
